home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / Snippets / Devices / SCSI Simple Sample / Src / MacSCSICommand.h < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-24  |  14.4 KB  |  438 lines  |  [TEXT/KAHL]

  1. /*                            MacScsiCommand.h                            */
  2. /*
  3.  * Scsi-specific definitions.
  4.  */
  5. #ifndef __MacSCSICommand__
  6. #define __MacSCSICommand__
  7.  
  8. #include <stddef.h>
  9. /*
  10.  * Include the O.S. files in a specific order to make sure that we have
  11.  * a definition for the _SCSIAtomic trap.
  12.  */
  13. #include <Traps.h>
  14. #ifndef _SCSIAtomic
  15. #define _SCSIAtomic    0xA089
  16. #endif
  17. #if 0
  18. #include <SCSI.h>
  19. #include "ACAM.h"
  20. #else
  21. /*
  22.  * This uses the new "common" SCSI.h which is not yet in the public
  23.  * header folders.
  24.  */
  25. #include "SCSI.h"
  26. #endif
  27.  
  28. #ifndef NULL
  29. #define NULL        0
  30. #endif
  31.  
  32. /*
  33.  * The 6-byte commands are used for most simple
  34.  * I/O requests.
  35.  */
  36. struct SCSI_6_Byte_Command {                /* Six-byte command            */
  37.     unsigned char        opcode;                /*  0                        */
  38.     unsigned char        lbn3;                /*  1 lbn in low 5            */
  39.     unsigned char        lbn2;                /*  2                        */
  40.     unsigned char        lbn1;                /*  3                        */
  41.     unsigned char        len;                /*  4                        */
  42.     unsigned char        ctrl;                /*  5                        */
  43. };
  44. typedef struct SCSI_6_Byte_Command SCSI_6_Byte_Command;
  45.  
  46. struct SCSI_10_Byte_Command {                /* Ten-byte command            */
  47.     unsigned char        opcode;                /*  0                        */
  48.     unsigned char        lun;                /*  1                        */
  49.     unsigned char        lbn4;                /*  2                        */
  50.     unsigned char        lbn3;                /*  3                        */
  51.     unsigned char        lbn2;                /*  4                        */
  52.     unsigned char        lbn1;                /*  5                        */
  53.     unsigned char        pad;                /*  6                        */
  54.     unsigned char        len2;                /*  7                        */
  55.     unsigned char        len1;                /*  8                        */
  56.     unsigned char        ctrl;                /*  9                        */
  57. };
  58. typedef struct SCSI_10_Byte_Command SCSI_10_Byte_Command;
  59.  
  60. struct SCSI_12_Byte_Command {                /* Twelve-byte command        */
  61.     unsigned char        opcode;                /*  0                        */
  62.     unsigned char        lun;                /*  1                        */
  63.     unsigned char        lbn4;                /*  2                        */
  64.     unsigned char        lbn3;                /*  3                        */
  65.     unsigned char        lbn2;                /*  4                        */
  66.     unsigned char        lbn1;                /*  5                        */
  67.     unsigned char        len4;                /*  6                        */
  68.     unsigned char        len3;                /*  7                        */
  69.     unsigned char        len2;                /*  8                        */
  70.     unsigned char        len1;                /*  9                        */
  71.     unsigned char        pad;                /* 10                        */
  72.     unsigned char        ctrl;                /* 11                        */
  73. };
  74. typedef struct SCSI_12_Byte_Command SCSI_12_Byte_Command;
  75.  
  76. /*
  77.  * This union defines all scsi commands.
  78.  */
  79. union SCSI_Command {
  80.     SCSI_6_Byte_Command        scsi6;
  81.     SCSI_10_Byte_Command    scsi10;
  82.     SCSI_12_Byte_Command    scsi12;
  83.     unsigned char                    scsi[12];
  84. };
  85. typedef union SCSI_Command SCSI_Command, *SCSI_CommandPtr;
  86.  
  87. /*
  88.  * Returned by a read-capacity command.
  89.  */
  90. struct SCSI_Capacity_Data {
  91.     unsigned char        lbn4;                /* Number                    */
  92.     unsigned char        lbn3;                /*  of                        */
  93.     unsigned char        lbn2;                /*   logical                */
  94.     unsigned char        lbn1;                /*    blocks                */
  95.     unsigned char        len4;                /* Length                    */
  96.     unsigned char        len3;                /*  of each                    */
  97.     unsigned char        len2;                /*   logical block            */
  98.     unsigned char        len1;                /*    in bytes                */
  99. };
  100. typedef struct SCSI_Capacity_Data SCSI_Capacity_Data;
  101.  
  102. struct SCSI_Inquiry_Data {                    /* Inquiry returns this        */
  103.     unsigned char        devType;            /*  0 Device type,            */
  104.     unsigned char        devTypeMod;            /*  1 Device type modifier    */
  105.     unsigned char        version;            /*  2 ISO/ECMA/ANSI version    */
  106.     unsigned char        format;                /*  3 Response data format    */
  107.     unsigned char        length;                /*  4 Additional Length        */
  108.     unsigned char        reserved5;            /*  5 Reserved                */
  109.     unsigned char        reserved6;            /*  6 Reserved                */
  110.     unsigned char        flags;                /*  7 Capability flags        */
  111.     unsigned char        vendor[8];            /*  8-15 Vendor-specific    */
  112.     unsigned char        product[16];        /* 16-31 Product id            */
  113.     unsigned char        revision[4];        /* 32-35 Product revision    */
  114.     unsigned char        vendorSpecific[20]; /* 36-55 Vendor stuff        */
  115.     unsigned char        moreReserved[40];    /* 56-95 Reserved            */
  116. };
  117. typedef struct SCSI_Inquiry_Data SCSI_Inquiry_Data;
  118.  
  119. /*
  120.  * This bit may be set in devTypeMod
  121.  */
  122. enum {
  123.     kScsiInquiryRMB = 0x80                    /* Removable medium    if set    */
  124. };
  125. /*
  126.  * These bits may be set in flags
  127.  */
  128. enum {
  129.     kScsiInquiryRelAdr    = 0x80,                /* Has relative addressing    */
  130.     kScsiInquiryWBus32    = 0x40,                /* Wide (32-bit) transfers    */
  131.     kScsiInquiryWBus16    = 0x20,                /* Wide (16-bit) transfers    */
  132.     kScsiInquirySync    = 0x10,                /* Synchronous transfers    */
  133.     kScsiInquiryLinked    = 0x08,                /* Linked commands ok        */
  134.     kScsiInquiryReserved = 0x04,
  135.     kScsiInquiryCmdQue    = 0x02,                /* Tagged cmd queuing ok    */
  136.     kScsiInquirySftRe    = 0x01                /* Soft reset alternative    */
  137. };
  138.  
  139. /*
  140.  * These are the device types that SCSI knows about.
  141.  */    
  142. enum {
  143.     kScsiDevTypeDirect = 0,
  144.     kScsiDevTypeSequential,
  145.     kScsiDevTypePrinter,
  146.     kScsiDevTypeProcessor,
  147.     kScsiDevTypeWorm,                        /* Write-once, read mult.    */
  148.     kScsiDevTypeCDROM,
  149.     kScsiDevTypeScanner,
  150.     kScsiDevTypeOptical,
  151.     kScsiDevTypeChanger,
  152.     kScsiDevTypeComm,
  153.     kScsiDevTypeMax                            /* For range testing        */
  154. };
  155.  
  156. /*
  157.  * This is the data that is returned after a GetExtendedStatus
  158.  * request. The errorCode gives a general indication of the error,
  159.  * which may be qualified by the additionalSenseCode and
  160.  * additionalSenseQualifier fields. These may be device (vendor)
  161.  * specific values, however. The info[] field contains additional
  162.  * information. For a media error, it contains the failing
  163.  * logical block number (most-significant byte first).
  164.  */
  165. struct SCSI_Sense_Data {                /* Request Sense result            */
  166.     unsigned char        errorCode;        /*  0    Class code, valid lbn    */
  167.     unsigned char        segmentNumber;    /*  1    Segment number            */
  168.     unsigned char        senseKey;        /*  2    Sense key and flags        */
  169.     unsigned char        info[4];
  170.     unsigned char        additionalSenseLength;
  171.     unsigned char        reservedForCopy[4];
  172.     unsigned char        additionalSenseCode;
  173.     unsigned char        additionalSenseQualifier;    
  174.     unsigned char        fruCode;        /* Field replacable unit code    */
  175.     unsigned char        senseKeySpecific[2];
  176.     unsigned char        additional[101];
  177. };
  178. typedef struct SCSI_Sense_Data SCSI_Sense_Data;
  179. /*
  180.  * The high-bit of errorCode signals whether there is a logical
  181.  * block. The low value signals whether there is a valid sense
  182.  */
  183. #define kScsiSenseHasLBN            0x80    /* Logical block number set    */
  184. #define kScsiSenseInfoValid            0x70    /* Is sense key valid?        */
  185. #define kScsiSenseInfoMask            0x70    /* Mask for sense info        */
  186. /*
  187.  * These bits may be set in the sense key
  188.  */
  189. #define kScsiSenseKeyMask            0x0F
  190. #define kScsiSenseILI                0x20    /* Illegal logical Length    */
  191. #define kScsiSenseEOM                0x40    /* End of media                */
  192. #define kScsiSenseFileMark            0x80    /* End of file mark            */
  193.  
  194. /*
  195.  * SCSI sense codes. (Returned after request sense).
  196.  */
  197. #define     kScsiSenseNone                0x00    /* No error                    */
  198. #define     kScsiSenseRecoveredErr        0x01    /* Warning                    */
  199. #define     kScsiSenseNotReady            0x02    /* Device not ready            */
  200. #define     kScsiSenseMediumErr        0x03    /* Device medium error        */
  201. #define     kScsiSenseHardwareErr        0x04    /* Device hardware error    */
  202. #define     kScsiSenseIllegalReq        0x05    /* Illegal request for dev.    */
  203. #define     kScsiSenseUnitAtn            0x06    /* Unit attention (not err)    */
  204. #define     kScsiSenseDataProtect        0x07    /* Data protection            */
  205. #define     kScsiSenseBlankCheck        0x08    /* Tape-specific error        */
  206. #define     kScsiSenseVendorSpecific    0x09    /* Vendor-specific error    */
  207. #define     kScsiSenseCopyAborted        0x0a    /* Copy request cancelled    */
  208. #define     kScsiSenseAbortedCmd        0x0b    /* Initiator aborted cmd.    */
  209. #define     kScsiSenseEqual            0x0c    /* Comparison equal            */
  210. #define     kScsiSenseVolumeOverflow    0x0d    /* Write past end mark        */
  211. #define     kScsiSenseMiscompare        0x0e    /* Comparison failed        */
  212. #define     kScsiSenseCurrentErr        0x70
  213. #define     kScsiSenseDeferredErr        0x71
  214.  
  215. /*
  216.  * Mode sense parameter header
  217.  */
  218. struct SCSI_ModeParamHeader {
  219.     unsigned char        modeDataLength;
  220.     unsigned char        mediumType;
  221.     unsigned char        deviceSpecific;
  222.     unsigned char        blockDescriptorLength;
  223. };
  224. typedef struct SCSI_ModeParamHeader SCSI_ModeParamHeader;
  225.  
  226. struct SCSI_ModeParamBlockDescriptor {
  227.     unsigned char        densityCode;
  228.     unsigned char        numberOfBlocks[3];
  229.     unsigned char        reserved;
  230.     unsigned char        blockLength[3];
  231. };
  232. typedef struct SCSI_ModeParamBlockDescriptor SCSI_ModeParamBlockDescriptor;
  233.  
  234. union SCSI_ModeParamPage {
  235.     unsigned char        data[1];
  236.     struct {
  237.         unsigned char    code;
  238.         unsigned char    length;
  239.     } page;
  240. };
  241. typedef union SCSI_ModeParamPage SCSI_ModeParamPage;
  242.  
  243. /*
  244.  * LogSense parameter header
  245.  */
  246. struct SCSI_LogSenseParamHeader {
  247.     unsigned char        pageCode;
  248.     unsigned char        reserved;
  249.     unsigned char        pageLength[2];
  250. };
  251. typedef struct SCSI_LogSenseParamHeader SCSI_LogSenseParamHeader;
  252.  
  253. /*
  254.  * Log parameter pages are variable-length with a fixed length header.
  255.  */
  256. union SCSI_LogSenseParamPage {
  257.     unsigned char        data[1];
  258.     struct {
  259.         unsigned char    parameterCode[2];
  260.         unsigned char    flags;
  261.         unsigned char    parameterLength;
  262.     } page;
  263. };
  264. typedef union SCSI_LogSenseParamPage SCSI_LogSenseParamPage;
  265.  
  266. /*
  267.  * SCSI command status (from status phase)
  268.  */
  269. #define     kScsiStatusGood            0x00    /* Normal completion        */
  270. #define     kScsiStatusCheckCondition    0x02    /* Need GetExtendedStatus    */
  271. #define     kScsiStatusConditionMet    0x04
  272. #define     kScsiStatusBusy            0x08    /* Device busy (self-test?)    */
  273. #define     kScsiStatusIntermediate    0x10    /* Intermediate status        */
  274. #define     kScsiStatusResConflict        0x18    /* Reservation conflict        */
  275. #define     kScsiStatusQueueFull        0x28    /* Target can't do command    */
  276. #define     kScsiStatusReservedMask    0x3e    /* Vendor specific?            */
  277.  
  278. /*
  279.  * SCSI command codes. Commands defined as ...6, ...10, ...12, are
  280.  * six-byte, ten-byte, and twelve-byte variants of the indicated command.
  281.  */
  282. /*
  283.  * These commands are supported for all devices.
  284.  */
  285. #define kScsiCmdChangeDefinition    0x40
  286. #define kScsiCmdCompare                0x39
  287. #define kScsiCmdCopy                0x18
  288. #define kScsiCmdCopyAndVerify        0x3a
  289. #define kScsiCmdInquiry                0x12
  290. #define kScsiCmdLogSelect            0x4c
  291. #define kScsiCmdLogSense            0x4d
  292. #define kScsiCmdModeSelect12        0x55
  293. #define kScsiCmdModeSelect6            0x15
  294. #define kScsiCmdModeSense12            0x5a
  295. #define kScsiCmdModeSense6            0x1a
  296. #define kScsiCmdReadBuffer            0x3c
  297. #define kScsiCmdRecvDiagResult        0x1c
  298. #define kScsiCmdRequestSense        0x03
  299. #define kScsiCmdSendDiagnostic        0x1d
  300. #define kScsiCmdTestUnitReady        0x00
  301. #define kScsiCmdWriteBuffer            0x3b
  302.  
  303. /*
  304.  * These commands are supported by direct-access devices only.
  305.  */
  306. #define kScsiCmdFormatUnit            0x04
  307. #define kSCSICmdCopy                0x18
  308. #define kSCSICmdCopyAndVerify        0x3a
  309. #define kScsiCmdLockUnlockCache        0x36
  310. #define kScsiCmdPrefetch            0x34
  311. #define kScsiCmdPreventAllowRemoval    0x1e
  312. #define kScsiCmdRead6                0x08
  313. #define kScsiCmdRead10                0x28
  314. #define kScsiCmdReadCapacity        0x25
  315. #define kScsiCmdReadDefectData        0x37
  316. #define kScsiCmdReadLong            0x3e
  317. #define kScsiCmdReassignBlocks        0x07
  318. #define kScsiCmdRelease                0x17
  319. #define kScsiCmdReserve                0x16
  320. #define kScsiCmdRezeroUnit            0x01
  321. #define kScsiCmdSearchDataEql        0x31
  322. #define kScsiCmdSearchDataHigh        0x30
  323. #define kScsiCmdSearchDataLow        0x32
  324. #define kScsiCmdSeek6                0x0b
  325. #define kScsiCmdSeek10                0x2b
  326. #define kScsiCmdSetLimits            0x33
  327. #define kScsiCmdStartStopUnit        0x1b
  328. #define kScsiCmdSynchronizeCache    0x35
  329. #define kScsiCmdVerify                0x2f
  330. #define kScsiCmdWrite6                0x0a
  331. #define kScsiCmdWrite10                0x2a
  332. #define kScsiCmdWriteAndVerify        0x2e
  333. #define kScsiCmdWriteLong            0x3f
  334. #define kScsiCmdWriteSame            0x41
  335.  
  336. /*
  337.  * These commands are supported by sequential devices.
  338.  */
  339. #define kScsiCmdRewind                0x01
  340. #define kScsiCmdWriteFilemarks        0x10
  341. #define kScsiCmdSpace                0x11
  342. #define kScsiCmdLoadUnload            0x1B
  343. /*
  344.  * ANSI SCSI-II for CD-ROM devices.
  345.  */
  346. #define kScsiCmdReadCDTableOfContents    0x43
  347.  
  348. /*
  349.  * Message codes (for Msg In and Msg Out phases). The Macintosh
  350.  * SCSI Manager can't really deal with these.
  351.  */
  352. #define kScsiMsgAbort                0x06
  353. #define kScsiMsgAbortTag            0x0d
  354. #define kScsiMsgBusDeviceReset        0x0c
  355. #define kScsiMsgClearQueue            0x0e
  356. #define kScsiMsgCmdComplete            0x00
  357. #define kScsiMsgDisconnect            0x04
  358. #define kScsiMsgIdentify            0x80
  359. #define kScsiMsgIgnoreWideResdue    0x23
  360. #define kScsiMsgInitiateRecovery    0x0f
  361. #define kScsiMsgInitiatorDetectedErr 0x05
  362. #define kScsiMsgLinkedCmdComplete    0x0a
  363. #define kScsiMsgLinkedCmdCompleteFlag 0x0b
  364. #define kScsiMsgParityErr            0x09
  365. #define kScsiMsgRejectMsg            0x07
  366. #define kScsiMsgModifyDataPtr        0x00 /* Extended msg        */
  367. #define kScsiMsgNop                    0x08
  368. #define kScsiMsgHeadOfQueueTag        0x21 /* Two byte msg        */
  369. #define kScsiMsgOrderedQueueTag        0x22 /* Two byte msg        */
  370. #define kScsiMsgSimpleQueueTag        0x20 /* Two byte msg        */
  371. #define kScsiMsgReleaseRecovery        0x10
  372. #define kScsiMsgRestorePointers        0x03
  373. #define kScsiMsgSaveDataPointers    0x02
  374. #define kScsiMsgSyncXferReq            0x01 /* Extended msg        */
  375. #define kScsiMsgWideDataXferReq        0x03 /* Extended msg        */
  376. #define kScsiMsgTerminateIOP        0x11
  377. #define kScsiMsgExtended            0x01
  378.  
  379. #define kScsiMsgTwoByte                0x20
  380. #define kScsiMsgTwoByteMin            0x20
  381. #define kScsiMsgTwoByteMax            0x2f
  382.  
  383. /*
  384.  * Default timeout times for SCSI commands.
  385.  */
  386. #define kScsiNormalCompletionTime    (30L)            /* 1/2 second                */
  387. /*
  388.  * Dratted DAT tape.
  389.  */
  390. #define kScsiDATCompletionTime        (60L * 60L);    /* One minute                */
  391. /*
  392.  * Yes, we do allow 90 seconds for spin-up of those dratted tape drives.
  393.  */
  394. #define kScsiSpinUpCompletionTime    (60L * 90L)
  395.  
  396. /*
  397.  * The NCR Bits, as returned by ScsiStat are only useful for maintenence
  398.  * and testing. Only the following bits are valid in the current
  399.  * implementation of the SCSI Manager. There is no guarantee that the
  400.  * bits are accessable, or useful, in future SCSI implementations.
  401.  * Note, however, that the Asynchronous SCSI Manager sets these bits to
  402.  * correspond to its current internal state.
  403.  *
  404.  * Using these bits, the following implications can be drawn:
  405.  *    kScsiStatBSY        Bus is busy. (On systems with multiple busses,
  406.  *                        there is no indication which bus is busy.)
  407.  *    kScsiStatREQ        Bus is busy. There is no way to determine whether
  408.  *                        the target has changed phase or has set REQ.
  409.  *    Bus Phase            If kScsiStatREQ and kSCSIStatBSY are set, the
  410.  *                        phase bits will indicate the current bus phase
  411.  *                        from the point of view of the initiator. It may
  412.  *                        not necessarily correspond exactly to the hardware
  413.  *                        bus phase.
  414.  */
  415. #define    kScsiStatBSY            (1 << 6)    /* Bus Busy                    */
  416. #define    kScsiStatREQ            (1 << 5)    /* Set if Bus Busy            */
  417. #define    kScsiStatMSG            (1 << 4)    /* MSG phase bit            */
  418. #define    kScsiStatCD                (1 << 3)    /* C/D phase bit            */
  419. #define    kScsiStatIO                (1 << 2)    /* I/O phase bit            */
  420. #define kScsiStatSEL            (1 << 1)    /* Select phase bit            */
  421. #define    kScsiPhaseMask    (kScsiStatMSG | kScsiStatCD | kScsiStatIO)
  422. #define kScsiPhaseShift    (2)
  423. #define    ScsiBusPhase(x) (((x) & kScsiPhaseMask) >> kScsiPhaseShift)
  424.  
  425. /*
  426.  * The phases are defined by a combination of bus lines. Note: these values
  427.  * have already been shifted. Other values are undefined. This is really
  428.  * only useful for the original SCSI manager.
  429.  */
  430. #define kScsiPhaseDATO        0    /* Data output (host -> device)            */
  431. #define kScsiPhaseDATI        1    /* Data input  (device -> host)            */
  432. #define kScsiPhaseCMD        2    /* Command                                */
  433. #define kScsiPhaseSTS        3    /* Status                                */
  434. #define kScsiPhaseMSGO        6    /* Message output                        */
  435. #define kScsiPhaseMSGI        7    /* Message input                        */
  436.  
  437. #endif /* __MacSCSICommand__ */
  438.